package com.dungeon.game;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import android.widget.ToggleButton;

import com.dungeon.game.Constants.Equipment_type_code;
import com.dungeon.game.Constants.Game_mode;
import com.dungeon.game.Constants.Position_code;
import com.dungeon.game.Constants.Potion_type;
import com.dungeon.game.Constants.Status_effect_code;
import com.dungeon.game.Party.Character;

public class MainActivity extends Activity {

	BossLayout myView;
	PartyPane myPartyPane;
	EnemyPane myEnemyPane;
	LinearLayout myLinearLayoutInsideScrollView;
	ActionChooser myActionChooserView;
	MyScrollView myScrollView;
	ToggleButton myPauseButton, myMuteButton;
	Button myFleeButton;
	GameLoop thread;
	public Handler updateHandler;
	boolean paused;

	String TAG = "MainActivity";

	public static final String PREFS_NAME = "MyPrefsFile";

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

	    Gamestate.init();

        setContentView(R.layout.activity_main);

        myView = (BossLayout)findViewById(R.id.LinearLayout1);

        myPartyPane = (PartyPane)findViewById(R.id.partypane);
        myPartyPane.listener.activity = this;
        myEnemyPane = (EnemyPane)findViewById(R.id.enemypane);
        myEnemyPane.listener.activity = this;
        myLinearLayoutInsideScrollView = (LinearLayout)findViewById(R.id.wrapper);
        myScrollView = (MyScrollView)findViewById(R.id.scrollView1);
        myScrollView.setBackgroundColor(Color.BLACK);
        myPauseButton = (ToggleButton)findViewById(R.id.pause_button);
        myMuteButton = (ToggleButton)findViewById(R.id.mute_button);
        myFleeButton = (Button)findViewById(R.id.flee_button);

        myActionChooserView = (ActionChooser)findViewById(R.id.ACBossLayout);
        myActionChooserView.setVisibility(View.INVISIBLE);
        
    	updateHandler = new Handler(){
    	    public void handleMessage(Message msg) {
    	        super.handleMessage(msg);
    	        if (!Gamestate.locked){
    	        	if (Gamestate.w.end_at>0 && Gamestate.w.end_at<Gamestate.w.clock){
    	        		Intent result = new Intent();
    	        		result.putExtra("clock", Gamestate.w.clock);
    	        		result.putExtra("won", Gamestate.w.dungeon_won);
    	        		result.putExtra("gold", Gamestate.w.removed_gold);
    	        		result.putExtra("n_items", Gamestate.w.items_found.size());
    	        		int count=0,count2=0;
    	        		for (Equipment_type_code it : Gamestate.w.items_found){
    	        			result.putExtra("item_"+count,it.ordinal());
    	        			count = count+1;
    	        		}
    	        		result.putExtra("n_chars", Gamestate.p.chars.size());
    	        		count = 0;
    	        		for (Character c : Gamestate.p.chars){
    	        			HashMap<Position_code,Integer> pos_counts = new HashMap<Position_code,Integer>();
    	        			for (Position_code p : c.pos_record){
    	        				if (pos_counts.containsKey(p))
    	        					pos_counts.put(p, pos_counts.get(p)+1);
    	        				else
    	        					pos_counts.put(p,1);
    	        			}
    	        			Position_code favorite = null;
    	        			int n_of_favorite = 0;
    	        			for (Position_code p : Position_code.values()){
    	        				if (pos_counts.containsKey(p) && pos_counts.get(p)>n_of_favorite){
    	        					favorite = p;
    	        					n_of_favorite = pos_counts.get(p);
    	        				}
    	        			}
    	        			if (favorite==null)
    	        				result.putExtra("favorite_pos_"+count,-1);
    	        			else
    	        				result.putExtra("favorite_pos_"+count,favorite.ordinal());
    	        			result.putExtra("xp_"+count,c.xp);
    	        			result.putExtra("survived_"+count,(c.alive && !c.has_status_effect(Status_effect_code.EF_PETRIFY)) || c.fled);
    	        			result.putExtra("n_potions_used_"+count,c.potions_used.size());
    	        			count2=0;
    	        			for (Potion_type p : c.potions_used){
    	        				result.putExtra("char_"+count+"_potion_"+count2,p.ordinal());
    	        			    count2 = count2 + 1;
    	        			}
    	        			count = count + 1;
    	        		}
    	        		setResult(RESULT_OK,result);
     	        		finish();
    	        	}
	    	        Gamestate.locked = true;
					Gamestate.update(msg.what);
					ArrayList<String> failed_sounds = new ArrayList<String>();
					for (String s : Gamestate.sound_queue){
						if (Gamestate.w.silence_until<=Gamestate.w.clock){
							if (!LaunchActivity.playSound(s)){
								failed_sounds.add(s);
							}
						}
					}
					Gamestate.sound_queue.clear();
					for (String s : failed_sounds){
						Gamestate.sound_queue.add(s);
					}
					for (Msg m : Gamestate.message_queue){
						if (m.image_name==null){
							SendImageTextMessage(null,m.text,m.color);
						} else {
							SendImageTextMessage(LaunchActivity.gi.getImageSmall(m.image_name),m.text,m.color);
						}
					}
					Gamestate.message_queue.clear();
					myView.invalidate();
					//Log.v(TAG,"invalidated");
					if ((Gamestate.mode==Game_mode.MODE_ACTION || Gamestate.mode==Game_mode.MODE_ENEMY_TARGET || Gamestate.mode==Game_mode.MODE_FRIENDLY_TARGET) && !Gamestate.actor.can_act()){
						myActionChooserView.setVisibility(View.INVISIBLE);
    					Gamestate.mode = Game_mode.MODE_NORMAL;
    	        	} else if (Gamestate.mode==Game_mode.MODE_ACTION && !Gamestate.actionchooser_created){
	    				Gamestate.dragging = null;
	    				Gamestate.actionchooser_created = true;
	    				myActionChooserView.setVisibility(View.VISIBLE);
	    				myActionChooserView.setup();
	    			} else if (Gamestate.mode==Game_mode.MODE_ACTION && myActionChooserView.action_number>=0){
	    				Gamestate.dragging = null;
	    				myActionChooserView.setVisibility(View.INVISIBLE);
	    				Gamestate.action = Gamestate.actor.actions.get(myActionChooserView.action_number);
	    				if (Gamestate.action.target_enemy()){
	    					Gamestate.mode = Game_mode.MODE_ENEMY_TARGET;
	    				} else if (Gamestate.action.target_friend()){
	    					Gamestate.mode = Game_mode.MODE_FRIENDLY_TARGET;
	    				} else {
	    					Gamestate.mode = Game_mode.MODE_NORMAL;
	    					Gamestate.action.trigger();
	    				}
	    			} else if (Gamestate.mode==Game_mode.MODE_ACTION && myActionChooserView.action_number==-99){
	    				Gamestate.dragging = null;
	    				myActionChooserView.setVisibility(View.INVISIBLE);
    					Gamestate.mode = Game_mode.MODE_NORMAL;
	    			} else if (Gamestate.mode==Game_mode.MODE_ACTION){
	    				myActionChooserView.refresh();
	    			}
					Gamestate.locked = false;
    	        }
    	    }
    	};

    	paused = true;

    	/* Do without these:
        SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
        mute = settings.getBoolean("mute", false); */
        myMuteButton.setChecked(Campaignstate.mute);

    	//Log.d(TAG,"finished main onCreate");
    }

    public void onFleeButton(View v){
    	boolean can_flee = Gamestate.w.check_can_flee();
        if (can_flee && !Gamestate.w.party_fleeing){
            Gamestate.add_sound("key");
            Gamestate.w.party_fleeing = true;
            Gamestate.add_message("Time to fight another day...",null,Color.WHITE);
        } else if (!can_flee){
            Gamestate.flee_attempts = Gamestate.flee_attempts + 1;
            if (Gamestate.flee_attempts>=3){
            	for (Character c: Gamestate.p.chars){
            		if (c.alive && !c.about_to_die){
            			c.take_damage(999);
            		}
            	}
            } else if (Gamestate.flee_attempts==2){
                Gamestate.add_message("Push Flee again to fail the mission...",null,Color.WHITE);
            } else {
            	Gamestate.add_sound("cancel");
            	Gamestate.add_message("There is no escape!",null,Color.WHITE);
            }
        }
    	Gamestate.dragging = null;
    	Gamestate.mode=Game_mode.MODE_NORMAL;
    	myActionChooserView.setVisibility(View.INVISIBLE);
    }

    public void onBackPressed() {
    	myFleeButton.performClick();
    	myFleeButton.setPressed(true);
    	myFleeButton.invalidate();
    	myFleeButton.postDelayed(new Runnable() {  //delay button
    	     public void run() {
    	    	 myFleeButton.setPressed(false);
    	    	 myFleeButton.invalidate();
    	        //any other associated action
    	     }
    	 }, 300);
	 }

    public void onPauseButton(View v){
    	if (paused){
    		unpause();
    	} else {
    		pause();
    	}
        Gamestate.add_sound("key");
    	Gamestate.dragging = null;
    	Gamestate.mode=Game_mode.MODE_NORMAL;
    }

    public void onMuteButton(View v){
    	Campaignstate.mute = !Campaignstate.mute;
    	Gamestate.dragging = null;
        Gamestate.add_sound("key");
    	Gamestate.mode=Game_mode.MODE_NORMAL;
    }

    void pause(){
    	Gamestate.mode=Game_mode.MODE_NORMAL;
    	myActionChooserView.setVisibility(View.INVISIBLE);
    	paused = true;
    	thread.running = false;
    	myView.setOnClickListener(new OnClickListener() {
    		public void onClick(View v) {
  	    	  unpause();
    	    }
    	});
    	myView.blocking = true;
        myPauseButton.setChecked(true);
    }

    void unpause(){
    	paused = false;
    	thread = new GameLoop();
        thread.last = System.currentTimeMillis();
        thread.running = true;
        thread.start();
        myView.setOnClickListener(null);
        myView.blocking = false;
        myPauseButton.setChecked(false);
    }

    void pause_for_dialog(){
    	paused = true;
    	thread.running = false;
    }

    void unpause_for_dialog(){
    	paused = false;
    	thread = new GameLoop();
        thread.last = System.currentTimeMillis();
        thread.running = true;
        thread.start();
    }

    protected void onStart(){
    	super.onStart();
    	unpause();
    	//Log.d(TAG,"finished main onStart");
    }

    public void onPause(){
        super.onPause();
/* do without this:
		SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
        SharedPreferences.Editor editor = settings.edit(); 
        editor.putBoolean("mute", mute);
        editor.commit(); */
        pause();
    	//Log.d(TAG,"finished main onPause");
    }

    public void onStop(){
    	super.onStop();
    	// Gamestate.dump(this,"my.sav");
    	//Log.d(TAG,"finished main onStop");
    }

    public class GameLoop extends Thread {
    	long now, last;
    	int elapsed;
    	boolean running;

    	public void run(){
    		// TO DO: I think Dave may have a problem around here
    		while (running){
    			try {
    			    Thread.sleep(10);
    			} catch (InterruptedException e) {}
    			now = System.currentTimeMillis();
    			elapsed = (int)(now - last);
    			last = now;
    			if (elapsed>0){
    				 MainActivity.this.updateHandler.sendEmptyMessage(elapsed);
    			}
    		}
    	}
    }

    public void SendTextMessage(String text){
        SendImageTextMessage(null,text,Color.WHITE);
    }

    public void SendImageTextMessage(Bitmap image,String text,int color){
    	TextView text_part = new TextView(this);
    	text_part.setText(text);
    	text_part.setTextColor(color);
    	text_part.setPadding(5, 5, 5, 5);
    	LinearLayout msg_layout = new LinearLayout(this);
    	msg_layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
    	msg_layout.setOrientation(LinearLayout.HORIZONTAL);
    	msg_layout.setGravity(Gravity.CENTER_VERTICAL);
    	if (image!=null && !image.equals("")){
        	ImageView image_part = new ImageView(this);
        	image_part.setImageDrawable(new BitmapDrawable(getResources(),image));
        	if (image.getHeight()==80)
        		image_part.setPadding(5, -5, 5, 2);
        	else
        		image_part.setPadding(5, 5, 5, 5);
        	msg_layout.addView(image_part);
        }
    	msg_layout.addView(text_part);
        SendMessage(msg_layout);
    }

    public void SendMessage(View message){
        myLinearLayoutInsideScrollView.addView(message);
        myScrollView.post(new Runnable() {
        	   public void run() {
        		   myScrollView.fullScroll(View.FOCUS_DOWN);
        	   }
        	});
    }

}
